#pragma once

#include <AVUIHitTestParameters3D.h>

namespace AVUI {

class MeshGeometry3D;
class RayHitTestResult;

/// <summary>Specifies the parameters of a hit test along a ray.</summary>
class RayHitTestParameters : public HitTestParameters3D
{
public:
    DECLARE_ELEMENT(RayHitTestParameters, HitTestParameters3D);

#pragma region Public Methods

    /// <summary>Creates an instance of the object that specifies the origin and direction of the ray along which to hit test.</summary>
    /// <param name="origin">Point3D at which the ray originates.</param>
    /// <param name="direction">Vector3D that indicates the direction of the ray.</param>
    RayHitTestParameters(const Point3D& origin, const Vector3D& direction);

#pragma endregion Public Methods

#pragma region Public Properties

    /// <summary> Gets or sets a <see cref="T:System.Windows.Media.Media3D.Vector3D" /> that indicates the direction (from its origin) of the ray along which to hit test. </summary>
    /// <returns>Vector3D that indicates the direction of the ray along which to hit test.</returns>
    Vector3D get_Direction() { return m_direction; }

    /// <summary> Gets the origin of the ray along which to hit test. </summary>
    /// <returns>Origin of the ray along which to hit test.</returns>
    Point3D get_Origin() { return m_origin; }

#pragma endregion Public Properties

public:

#pragma region Internal Methods

    void ClearResults();
    void GetLocalLine(Point3D* pOrigin, Vector3D* pDirection);

    HitTestResultBehavior::Enum RaiseCallback(HitTestResultCallback* pResultCallback, HitTestFilterCallback* pFilterCallback, HitTestResultBehavior::Enum lastResult);
    HitTestResultBehavior::Enum RaiseCallback(HitTestResultCallback* pResultCallback, HitTestFilterCallback* pFilterCallback, HitTestResultBehavior::Enum lastResult, float distanceAdjustment);
    void ReportResult(MeshGeometry3D* pMeshHit, const Point3D& pointHit, float distanceToRayOrigin, int vertexIndex1, int vertexIndex2, int vertexIndex3, const Point& barycentric);

#pragma endregion Internal Methods

#pragma region Internal Properties

    bool get_IsRay() { return m_isRay; }

#pragma endregion Internal Properties

private:

#pragma region Private Fields

    Vector3D m_direction;
    bool m_isRay;
    Point3D m_origin;
    ItemStructList< TRefCountedPtr<RayHitTestResult> > m_results;

#pragma endregion Private Fields

};

}; // namespace AVUI


